#include "DescriptorsRepository.h"

DescriptorsRepositorySp DescriptorsRepository::descriptorsRepository;

DescriptorsRepositorySp DescriptorsRepository::GetInstance()
{
	if ( !descriptorsRepository )
	{
		descriptorsRepository = DescriptorsRepositorySp( new DescriptorsRepository() );
	}

	return descriptorsRepository;
}

bool DescriptorsRepository::ExistCommand( string commandName )
{
	CommandDescriptorSpMap::iterator it = commands.find(commandName);
	if ( it == commands.end() )
	{
		return false;
	}

	return true;
}

bool DescriptorsRepository::ExistType( string typeName )
{
	TypeDescriptorSpMap::iterator it = types.find(typeName);
	if ( it == types.end() )
	{
		return false;
	}

	return true;
}

StringVectorSp DescriptorsRepository::GetCommandNames()
{
	StringVectorSp v(new StringVector);

	BOOST_FOREACH( CommandDescriptorSpMapPair elem, commands )
	{
		v->push_back( elem.first );
	}

	return v;
}

StringVectorSp DescriptorsRepository::GetTypeNames()
{
	StringVectorSp v(new StringVector);

	BOOST_FOREACH( TypeDescriptorSpMapPair elem, types)
	{
		v->push_back( elem.first );
	}

	return v;
}

CommandDescriptorSp DescriptorsRepository::GetCommandDescriptor( string commandName )
{
	if ( !ExistCommand(commandName) )
	{
		throw SArgumentException("There is not a command with the name '" + commandName + "'");
	}

	CommandDescriptorSp cd = commands[commandName];
	return cd;
}

TypeDescriptorSp DescriptorsRepository::GetTypeDescriptor( string typeName )
{
	if ( !ExistType(typeName) )
	{
		throw SArgumentException("There is not a type with the name '" + typeName + "'");
	}

	TypeDescriptorSp td = types[typeName];	
	return td;
}

SEnumTypeDescriptorSp DescriptorsRepository::GetEnumTypeDescriptor( string typeName )
{
	return GetTypeDescriptor(typeName)->As<SEnumTypeDescriptor>();
}

SVectorTypeDescriptorSp DescriptorsRepository::GetVectorTypeDescriptor( string typeName )
{
	return GetTypeDescriptor(typeName)->As<SVectorTypeDescriptor>();
}

SStructTypeDescriptorSp DescriptorsRepository::GetStructTypeDescriptor( string typeName )
{
	return GetTypeDescriptor(typeName)->As<SStructTypeDescriptor>();
}

void DescriptorsRepository::AddCommandDescriptor( CommandDescriptorSp cd )
{
	commands[ cd->GetFullyQualifiedName() ] = cd;
}

void DescriptorsRepository::AddTypeDescriptor( TypeDescriptorSp td )
{
	types[ td->GetFullyQualifiedName() ] = td;
}
